#ifndef EXCHANGEBASE_H
#define EXCHANGEBASE_H

#include "ExchangeIO.h"
#include "ExchangeMatrix.h"


namespace  AMCAX::Exchange {
    class ExchangeDocumentInstance;
    class ExchangeDocumentReference ;

    /// @ingroup support file type 
    /// @brief Used to identify the file type, primarily associated with the file extension.
    /// 
    enum class EXCHANGE_FILE_TYPE
    {
        AMX,STEP, IGES,STL,OBJ,GLTF, DXF, DWG, BREP,INTEROP, NONE
    } ;

    /// @ingroup The type of the input file
    /// @brief What are the supported methods for the input file type.
    /// 
    enum class INPUT_FILE_TYPE
    {
        FILE_PATH,
        FILE_INPUT_STREAM,
        FILE_OUTPUT_STREAM,
        UNKNOWN
    } ;

    /// @ingroup The type of the output file
    /// @brief What are the supported methods for the output file type.
    /// 
    enum class OUTPUT_FILE_TYPE
    {
        FILE_PATH,
        FILE_OUTPUT_STREAM,
        UNKNOWN
    } ;

class ExchangeBase : public ExchangeIO{
    public:
        void Read();
        const std::vector<std::shared_ptr<ExchangeObject>> & GetShapes() override
        {
            return exchangeObjectList_ ;
        }

        const std::shared_ptr<ExchangeDocumentInstance> & GetDocumentRootInstance() override
        {
            return exchangeDocumentRootInstance_ ;
        }

        void SetExchangeParameter(ExchangeParameter *outputParameter)
        {
            exchangeParameter_ = outputParameter ;
        }
    protected:
        ExchangeBase(std::string filePath);
        ExchangeBase(std::ifstream *fileStream,std::ofstream *outFileStream, EXCHANGE_FILE_TYPE fileType);
        ExchangeBase(std::shared_ptr<std::fstream> fileStreamAmx, std::shared_ptr<std::fstream> outFileStreamAmx, EXCHANGE_FILE_TYPE fileType);

        virtual void ReadFromFilePath() = 0;
        virtual void ReadFromFileStream() = 0;
        EXCHANGE_FILE_TYPE GetFileType(){return fileType_ ;} ;
        ExchangeParameter *GetExchangeParameter() {return exchangeParameter_ ;};

        void NestedExchangeShapeToFlatRecursion(std::vector<std::shared_ptr<ExchangeObject>>& flatShapes,std::shared_ptr<ExchangeObject> rawShape) ;
        void NestedExchangeShapeToFlat(std::vector<std::shared_ptr<ExchangeObject>>& flatShapes,std::vector<std::shared_ptr<ExchangeObject>> rawShape) ;

        void TransformToPartToposhapeRecursion(const std::shared_ptr<ExchangeDocumentReference> &reference,const  ExchangeMatrix transfrom) ;
        void ToPart() ;
    
    protected:
        EXCHANGE_FILE_TYPE fileType_ = EXCHANGE_FILE_TYPE::NONE ;
        INPUT_FILE_TYPE inputFileType_ = INPUT_FILE_TYPE::UNKNOWN ;
        OUTPUT_FILE_TYPE outputFileType_ = OUTPUT_FILE_TYPE::UNKNOWN ;
        std::string filePath_ ;
        std::vector<std::shared_ptr<ExchangeObject>> exchangeObjectList_;
        std::vector<std::shared_ptr<ExchangeObject>> exchangePartObjectList_;
        std::shared_ptr<ExchangeDocumentInstance> exchangeDocumentRootInstance_;
        ExchangeParameter *exchangeParameter_{nullptr} ;
        std::ifstream *inFileStream_{nullptr} ;
        std::ofstream *outFileStream_{nullptr} ;

        // amx
        std::shared_ptr<std::fstream> inFileStreamAmx_{nullptr} ;
        std::shared_ptr<std::fstream> outFileStreamAmx_{nullptr} ;
} ;

}

#endif // EXCHANGEBASE_H